package com.ybear.ybcomponent.widget.damping

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.animation.Interpolator
import android.widget.HorizontalScrollView
import androidx.core.content.withStyledAttributes
import com.ybear.ybcomponent.R
import com.ybear.ybcomponent.widget.damping.helper.DampingHelper
import com.ybear.ybcomponent.widget.damping.helper.IDamping
import com.ybear.ybcomponent.widget.damping.helper.OnDampingScrollListener
import com.ybear.ybcomponent.widget.damping.helper.Orientation

/**
 * 带有阻尼的水平滑动布局
 */
open class DampingHorizontalScrollView : HorizontalScrollView, IDamping {
    private val mHelper = DampingHelper()
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : this(
        context, attrs, defStyleAttr, 0
    )

    constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
        context.withStyledAttributes( attrs, R.styleable.DampingHorizontalScrollView, defStyleAttr, defStyleRes ) {
            setDampingValue(
                getFloat(
                    R.styleable.DampingHorizontalScrollView_damDampingValue, 0.5f
                )
            )
            setRecoverAnimationDuration(
                (getString(
                    R.styleable.DampingHorizontalScrollView_damRecoverAnimationDuration
                ) ?: "300").toLong()
            )
            setEnablePullDown(
                getBoolean(
                    R.styleable.DampingHorizontalScrollView_damEnablePullDown, true
                )
            )
            setEnablePullUp(
                getBoolean(
                    R.styleable.DampingHorizontalScrollView_damEnablePullUp, true
                )
            )
            setDampingOrientation(
                getInt(
                    R.styleable.DampingHorizontalScrollView_damOrientation, Orientation.HORIZONTAL
                )
            )
        }
    }

    /**
     * 当以当前 View 为根的视图层次结构完成 inflate 操作后会被调用
     */
    override fun onFinishInflate() {
        super.onFinishInflate()
        // 将 onFinishInflate() 事件传递给 DampingHelper 处理
        mHelper.onFinishInflate(this)
    }

    /**
     * 用于在布局阶段为 View 的子视图分配大小和位置
     * @param changed 如果视图的大小或位置发生了变化，则为 true；否则为 false
     * @param left 相对于父视图的左边界位置
     * @param top 相对于父视图的上边界位置
     * @param right 相对于父视图的右边界位置
     * @param bottom 相对于父视图的下边界位置
     */
    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        // 将 onLayout() 事件传递给 DampingHelper 处理
        mHelper.onLayout(left, top, right, bottom)
    }

    /**
     * 分发触摸事件
     * @param ev 触摸事件
     * @return 是否消费了触摸事件
     */
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        // 将触摸事件分发给 DampingHelper 处理
        return mHelper.dispatchTouchEvent(this, ev)
    }

    /**
     * 将触摸事件传递给父类处理
     * @param ev 触摸事件
     * @return 是否消费了触摸事件
     */
    override fun superDispatchTouchEvent(ev: MotionEvent): Boolean {
        // 直接调用父类的 dispatchTouchEvent() 方法
        return super.dispatchTouchEvent(ev)
    }

    // 下面是 IDamping 接口方法的实现，它们都直接调用了 mHelper 的对应方法

    /**
     * 设置阻尼滑动监听器
     * @param listener 监听器
     */
    override fun setOnDampingScrollListener(listener: OnDampingScrollListener?) {
        mHelper.setOnDampingScrollListener(listener)
    }

    /**
     * 设置阻尼系数，数值越高，阻尼效果越明显
     * @param value 阻尼系数
     */
    override fun setDampingValue(value: Float) {
        mHelper.setDampingValue(value)
    }

    /**
     * 设置恢复动画时长
     * @param duration 动画时长，单位毫秒
     */
    override fun setRecoverAnimationDuration(duration: Long) {
        mHelper.setRecoverAnimationDuration(duration)
    }

    /**
     * 设置恢复动画插值器
     * @param i 插值器
     */
    override fun setRecoverInterpolator(i: Interpolator) {
        mHelper.setRecoverInterpolator(i)
    }

    /**
     * 设置是否启用阻尼效果
     * @param enable true 启用，false 禁用
     */
    override fun setEnabledDamping(enable: Boolean) {
        mHelper.setEnabledDamping(enable)
    }

    /**
     * 获取阻尼效果是否启用
     * @return true 启用，false 禁用
     */
    override fun isEnabledDamping(): Boolean {
        return mHelper.isEnabledDamping()
    }

    /**
     * 设置是否启用下拉阻尼
     * @param enable true 启用，false 禁用
     */
    override fun setEnablePullDown(enable: Boolean) {
        mHelper.setEnablePullDown(enable)
    }

    /**
     * 设置是否启用上拉阻尼
     * @param enable true 启用，false 禁用
     */
    override fun setEnablePullUp(enable: Boolean) {
        mHelper.setEnablePullUp(enable)
    }

    /**
     * 设置阻尼滑动方向
     * @param orientation 方向，可以是 [Orientation.HORIZONTAL] 或 [Orientation.VERTICAL]
     */
    override fun setDampingOrientation(orientation: Int) {
        mHelper.setDampingOrientation(orientation)
    }
}